package api

import (
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"strconv"

	"gopkg.in/yaml.v2"

	"goVector/pkg/db"
	"goVector/pkg/embedding"
	"goVector/pkg/model"

	"github.com/gin-gonic/gin"
)

// VectorServer 表示向量服务器
type VectorServer struct {
	db               db.VectorDB
	embedder         embedding.Embedder
	collectionMgr    *db.CollectionManager
	activeCollection string
}

// NewVectorServer 创建新的向量服务器
func NewVectorServer(db db.VectorDB, embedder embedding.Embedder) *VectorServer {
	return &VectorServer{
		db:       db,
		embedder: embedder,
	}
}

// NewVectorServerWithCollections 创建支持集合管理的向量服务器
func NewVectorServerWithCollections(collectionMgr *db.CollectionManager, embedder embedding.Embedder) *VectorServer {
	return &VectorServer{
		collectionMgr: collectionMgr,
		embedder:      embedder,
	}
}

// SetupRoutes 设置路由
func (s *VectorServer) SetupRoutes(r *gin.RouterGroup) {
	// 文档管理
	r.POST("/documents", s.CreateDocument)
	r.PUT("/documents/:id", s.UpdateDocument)
	r.DELETE("/documents/:id", s.DeleteDocument)
	r.DELETE("/documents", s.DeleteAllDocuments) // 添加删除所有文档的路由
	r.GET("/documents/:id", s.GetDocument)
	r.GET("/documents", s.ListDocuments)
	r.POST("/search", s.SearchDocuments)
	r.POST("/batch/documents", s.BatchCreateDocuments) // 批量创建文档

	// 集合管理
	r.POST("/collections", s.CreateCollection)
	r.GET("/collections", s.ListCollections)
	r.GET("/collections/:name", s.GetCollection)
	r.DELETE("/collections/:name", s.DeleteCollection)
	r.POST("/collections/:name/use", s.UseCollection)

	// 配置管理
	r.GET("/config", s.GetConfig)
	r.PUT("/config", s.UpdateConfig)
}

// ListDocuments 获取文档列表
func (s *VectorServer) ListDocuments(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 获取分页参数
	limitStr := c.DefaultQuery("limit", "10")
	offsetStr := c.DefaultQuery("offset", "0")

	limit, err := strconv.Atoi(limitStr)
	if err != nil || limit < 1 {
		limit = 10
	}

	offset, err := strconv.Atoi(offsetStr)
	if err != nil || offset < 0 {
		offset = 0
	}

	// 获取文档列表
	docs, total, err := activeDB.ListDocuments(limit, offset)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取文档列表失败: " + err.Error()})
		return
	}

	// 转换为不含向量的文档列表
	lightDocs := make([]model.LightDocument, len(docs))
	for i, doc := range docs {
		lightDocs[i] = model.LightDocument{
			ID:      doc.ID,
			Content: doc.Content,
		}
	}

	c.JSON(http.StatusOK, gin.H{
		"documents": lightDocs,
		"total":     total,
		"limit":     limit,
		"offset":    offset,
	})
}

// 获取当前活动的数据库实例
func (s *VectorServer) getActiveDB() (db.VectorDB, error) {
	// 如果使用集合管理
	if s.collectionMgr != nil {
		if s.activeCollection == "" {
			return nil, fmt.Errorf("未选择活动集合，请先使用POST /collections/{name}/use接口选择集合")
		}

		return s.collectionMgr.GetCollection(s.activeCollection)
	}

	// 使用单一数据库
	return s.db, nil
}

// CreateDocument 创建新文档
func (s *VectorServer) CreateDocument(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	var req model.NewDocumentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 获取文本嵌入向量
	vector, err := s.embedder.GetEmbedding(req.Content)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取嵌入向量失败: " + err.Error()})
		return
	}

	// 保存文档到数据库
	id, err := activeDB.AddDocument(req.Content, vector)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存文档失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusCreated, gin.H{
		"id":      id,
		"content": req.Content,
		"message": "文档创建成功",
	})
}

// UpdateDocument 更新文档
func (s *VectorServer) UpdateDocument(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return

	}

	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID格式"})
		return
	}

	var req model.UpdateDocumentRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 确保ID匹配
	if id != req.ID {
		c.JSON(http.StatusBadRequest, gin.H{"error": "URL中的ID与请求体中的ID不匹配"})
		return
	}

	// 获取文本嵌入向量
	vector, err := s.embedder.GetEmbedding(req.Content)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取嵌入向量失败: " + err.Error()})
		return
	}

	// 更新数据库中的文档
	err = activeDB.UpdateDocument(id, req.Content, vector)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "更新文档失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"id":      id,
		"content": req.Content,
		"message": "文档更新成功",
	})
}

// DeleteDocument 删除文档
func (s *VectorServer) DeleteDocument(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID格式"})
		return
	}

	err = activeDB.DeleteDocument(id)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除文档失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"id":      id,
		"message": "文档删除成功",
	})
}

// DeleteAllDocuments 删除所有文档
func (s *VectorServer) DeleteAllDocuments(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 检查数据库是否支持批量删除功能
	bulkDeleter, ok := activeDB.(interface {
		DeleteAllDocuments() (int64, error)
	})

	// 如果不支持批量删除，返回错误
	if !ok {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "当前数据库不支持批量删除操作"})
		return
	}

	// 执行批量删除
	count, err := bulkDeleter.DeleteAllDocuments()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除所有文档失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"deleted": count,
		"message": "所有文档已删除",
	})
}

// GetDocument 获取指定ID的文档
func (s *VectorServer) GetDocument(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	idStr := c.Param("id")
	id, err := strconv.ParseInt(idStr, 10, 64)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID格式"})
		return
	}

	doc, err := activeDB.GetDocument(id)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "获取文档失败: " + err.Error()})
		return
	}

	// 返回不含向量数据的轻量级文档
	lightDoc := model.LightDocument{
		ID:      doc.ID,
		Content: doc.Content,
	}

	c.JSON(http.StatusOK, lightDoc)
}

// SearchDocuments 搜索相似文档
func (s *VectorServer) SearchDocuments(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	var req model.SearchRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 设置默认值
	if req.Limit <= 0 {
		req.Limit = 10
	}
	if req.MinScore <= 0 {
		req.MinScore = 0.5
	}

	// 获取查询文本的嵌入向量
	queryVector, err := s.embedder.GetEmbedding(req.Query)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取查询嵌入向量失败: " + err.Error()})
		return
	}

	// 搜索相似文档
	results, err := activeDB.SearchSimilar(queryVector, req.Limit, req.MinScore)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "搜索文档失败: " + err.Error()})
		return
	}

	// 将结果转换为不包含向量的轻量级结果
	var lightResults []model.LightSearchResult
	for _, result := range results {
		lightResults = append(lightResults, model.LightSearchResult{
			Document: model.LightDocument{
				ID:      result.Document.ID,
				Content: result.Document.Content,
			},
			Score: result.Score,
		})
	}

	c.JSON(http.StatusOK, gin.H{
		"query":   req.Query,
		"results": lightResults,
	})
}

// BatchCreateDocuments 批量创建多个文档
func (s *VectorServer) BatchCreateDocuments(c *gin.Context) {
	activeDB, err := s.getActiveDB()
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	var req model.BatchDocumentCreateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 批处理结果
	response := model.BatchDocumentCreateResponse{
		Message: "批量创建文档处理完成",
		Results: make([]model.DocumentCreateResult, len(req.Documents)),
	}

	for i, docReq := range req.Documents {
		result := model.DocumentCreateResult{
			Content: docReq.Content,
			Success: false,
		}

		// 获取文本嵌入向量
		vector, err := s.embedder.GetEmbedding(docReq.Content)
		if err != nil {
			result.ErrorMsg = "获取嵌入向量失败: " + err.Error()
			response.Failed++
			response.Results[i] = result
			continue
		}

		// 保存文档到数据库
		id, err := activeDB.AddDocument(docReq.Content, vector)
		if err != nil {
			result.ErrorMsg = "保存文档失败: " + err.Error()
			response.Failed++
			response.Results[i] = result
			continue
		}

		// 记录成功
		result.ID = id
		result.Success = true
		response.Created++
		response.Results[i] = result
	}

	c.JSON(http.StatusCreated, response)
}

// CreateCollection 创建新的文档集合
func (s *VectorServer) CreateCollection(c *gin.Context) {
	if s.collectionMgr == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "服务器未启用集合管理功能"})
		return
	}

	var req model.CollectionCreateRequest
	if err := c.ShouldBindJSON(&req); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
		return
	}

	// 创建集合
	_, err := s.collectionMgr.CreateCollection(req.Collection)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "创建集合失败: " + err.Error()})
		return
	}

	// 设置为当前活动集合
	s.activeCollection = req.Collection.Name

	c.JSON(http.StatusCreated, gin.H{
		"name":        req.Collection.Name,
		"file_path":   req.Collection.FilePath,
		"memory_mode": req.Collection.MemoryMode,
		"message":     "集合创建成功",
		"active":      true,
	})
}

// ListCollections 列出所有可用的集合
func (s *VectorServer) ListCollections(c *gin.Context) {
	if s.collectionMgr == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "服务器未启用集合管理功能"})
		return
	}

	// 获取集合名称列表和元数据
	collectionsInfo, err := s.collectionMgr.GetCollectionsInfo()
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "获取集合信息失败: " + err.Error()})
		return
	}

	// 转换为增强的集合信息
	collections := make([]model.CollectionInfo, 0, len(collectionsInfo))
	for _, info := range collectionsInfo {
		collections = append(collections, model.CollectionInfo{
			Name:          info.Name,
			IsActive:      (info.Name == s.activeCollection),
			DocumentCount: info.DocumentCount,
		})
	}

	// 返回响应
	response := model.CollectionListResponse{
		Collections: collections,
	}

	c.JSON(http.StatusOK, response)
}

// GetCollection 获取集合信息
func (s *VectorServer) GetCollection(c *gin.Context) {
	if s.collectionMgr == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "服务器未启用集合管理功能"})
		return
	}

	name := c.Param("name")

	// 获取集合（只是检查集合是否存在）
	_, err := s.collectionMgr.GetCollection(name)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "获取集合失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"name":   name,
		"active": name == s.activeCollection,
	})
}

// DeleteCollection 删除集合
func (s *VectorServer) DeleteCollection(c *gin.Context) {
	if s.collectionMgr == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "服务器未启用集合管理功能"})
		return
	}

	name := c.Param("name")

	// 删除集合
	err := s.collectionMgr.DeleteCollection(name)
	if err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "删除集合失败: " + err.Error()})
		return
	}

	// 如果删除的是当前活动集合，清除活动集合
	if s.activeCollection == name {
		s.activeCollection = ""
	}

	c.JSON(http.StatusOK, gin.H{
		"name":    name,
		"message": "集合删除成功",
	})
}

// UseCollection 设置活动集合
func (s *VectorServer) UseCollection(c *gin.Context) {
	if s.collectionMgr == nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "服务器未启用集合管理功能"})
		return
	}

	name := c.Param("name")

	// 检查集合是否存在
	_, err := s.collectionMgr.GetCollection(name)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "集合不存在: " + err.Error()})
		return
	}

	// 设置为活动集合
	s.activeCollection = name

	c.JSON(http.StatusOK, gin.H{
		"name":    name,
		"message": "已切换到集合",
		"active":  true,
	})
}

// GetConfig 获取当前配置
func (s *VectorServer) GetConfig(c *gin.Context) {
	configPath := c.DefaultQuery("path", "config.yaml")

	// 读取配置文件
	data, err := os.ReadFile(configPath)
	if err != nil {
		c.JSON(http.StatusNotFound, gin.H{"error": "读取配置文件失败: " + err.Error()})
		return
	}

	c.Header("Content-Type", "text/plain")
	c.String(http.StatusOK, string(data))
}

// UpdateConfig 更新配置文件
func (s *VectorServer) UpdateConfig(c *gin.Context) {
	configPath := c.DefaultQuery("path", "config.yaml")

	// 读取请求体中的YAML内容
	body, err := io.ReadAll(c.Request.Body)
	if err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "读取请求内容失败: " + err.Error()})
		return
	}

	// 验证YAML格式是否正确
	var yamlData interface{}
	if err := yaml.Unmarshal(body, &yamlData); err != nil {
		c.JSON(http.StatusBadRequest, gin.H{"error": "YAML格式不正确: " + err.Error()})
		return
	}

	// 备份旧的配置文件
	backupPath := configPath + ".bak"
	if data, err := os.ReadFile(configPath); err == nil {
		if err := os.WriteFile(backupPath, data, 0644); err != nil {
			log.Printf("备份配置文件失败: %v", err)
		}
	}

	// 写入新的配置文件
	if err := os.WriteFile(configPath, body, 0644); err != nil {
		c.JSON(http.StatusInternalServerError, gin.H{"error": "保存配置文件失败: " + err.Error()})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"message": "配置已更新，重启服务器后生效",
		"backup":  backupPath,
	})
}

// Shutdown 优雅关闭服务器，保存所有数据
func (s *VectorServer) Shutdown() error {
	var err error

	// 如果使用集合管理
	if s.collectionMgr != nil {
		err = s.collectionMgr.CloseAll() // 确保 CloseAll 会保存所有集合数据
		return err
	}

	// 使用单一数据库
	if s.db != nil {
		// 调用 SaveToDisk (如果实现了)
		if saver, ok := s.db.(interface{ SaveToDisk() error }); ok {
			if err = saver.SaveToDisk(); err != nil {
				return fmt.Errorf("保存数据失败: %w", err)
			}
		}
		return s.db.Close()
	}

	return nil
}
